package com.shuwen.gcdj.service.common;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shuwen.gcdj.common.api.CommonPage;
import com.shuwen.gcdj.common.api.CommonResult;
import com.shuwen.gcdj.bean.AddResp;
import com.shuwen.gcdj.bean.VoidResp;
import com.shuwen.gcdj.bean.common.request.AddCommonFieldReq;
import com.shuwen.gcdj.bean.common.request.DeleteCommonFieldReq;
import com.shuwen.gcdj.bean.common.request.SearchCommonFieldListReq;
import com.shuwen.gcdj.bean.common.request.SearchPagingCommonFieldListReq;
import com.shuwen.gcdj.bean.common.request.UpdateCommonFieldReq;
import com.shuwen.gcdj.bean.common.response.SearchCommonFieldListItemResp;
import com.shuwen.gcdj.common.enums.ErrorCode;
import com.shuwen.gcdj.common.error.ErrorReport;
import com.shuwen.gcdj.dto.account.InitUserDto;
import com.shuwen.gcdj.entity.CommonField;
import com.shuwen.gcdj.mapper.mysql.CommonFieldMapper;
import com.shuwen.gcdj.service.BaseService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@AllArgsConstructor
@Slf4j
public class CommonFieldService extends BaseService<CommonFieldMapper, CommonField> {
    private final CommonFieldMapper commonFieldMapper;

    /**
     * 通用字段管理 - 添加
     *
     * @param req         AddCommonFieldReq
     * @param initUserDto InitUserDto
     * @return CommonResult<AddResp>
     */
    public CommonResult<AddResp> add(AddCommonFieldReq req, InitUserDto initUserDto) {
        // check add params
        ErrorCode check = checkAdd(req);
        if (ErrorReport.hasError(check)) {
            return CommonResult.failed(check);
        }

        CommonField cp = new CommonField();
        BeanUtils.copyProperties(req, cp);
        addExtField(cp, initUserDto);
        boolean res = save(cp);
        if (res) {
            AddResp resp = new AddResp();
            resp.setId(cp.getId());
            return CommonResult.success(resp);
        }

        return CommonResult.failed(ErrorCode.FAILED);
    }

    /**
     * 通用字段管理 - 编辑
     *
     * @param req         UpdateCommonFieldReq
     * @param initUserDto InitUserDto
     * @return CommonResult<VoidResp>
     */
    public CommonResult<VoidResp> updateField(UpdateCommonFieldReq req, InitUserDto initUserDto) {
        // check update params
        ErrorCode check = checkUpdate(req);
        if (!ErrorReport.hasError(check)) {
            CommonField cp = new CommonField();
            BeanUtils.copyProperties(req, cp);
            addExtField(cp, initUserDto);
            boolean res = updateById(cp);
            if (res) {
                return CommonResult.success(new VoidResp());
            }

            return CommonResult.failed(ErrorCode.FAILED);
        }

        return CommonResult.failed(check);
    }

    private void addExtField(CommonField cp, InitUserDto initUserDto) {
        if (cp != null && initUserDto != null && initUserDto.getUserId() != null && !initUserDto.getUserId().isEmpty()) {
            cp.setCreateId(initUserDto.getUserId());
            cp.setUpdateId(initUserDto.getUserId());
        }
    }

    /**
     * 通用字段管理 - 删除
     *
     * @param req         DeleteCommonFieldReq
     * @param initUserDto InitUserDto
     * @return CommonResult<VoidResp>
     */
    public CommonResult<VoidResp> deleteField(DeleteCommonFieldReq req, InitUserDto initUserDto) {
        ErrorCode check = checkDelete(req);
        if (ErrorReport.hasError(check)) {
            return CommonResult.failed(check);
        }
        commonFieldMapper.deleteById(req.getId());

        return CommonResult.success(new VoidResp());
    }

    /**
     * 列表页接口 - 分页
     *
     * @param req SearchPagingCommonFieldListReq
     * @return CommonResult<CommonPage < SearchCommonFieldListItemResp>>
     */
    public CommonResult<CommonPage<SearchCommonFieldListItemResp>> getPagingCommonFieldList(SearchPagingCommonFieldListReq req) {
        Page<SearchCommonFieldListItemResp> page = new Page<>(req.getPageNum(), req.getPageSize(), true);
        IPage<SearchCommonFieldListItemResp> data = commonFieldMapper.getPagingCommonFieldList(page, req);
        List<SearchCommonFieldListItemResp> res = data.getRecords();
        Page<SearchCommonFieldListItemResp> resPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        resPage.setRecords(res);
        return CommonResult.success(CommonPage.restPage(resPage));
    }

    /**
     * 列表接口 - 不分页
     *
     * @param req SearchCommonFieldListReq
     * @return List<SearchCommonFieldListItemResp>
     */
    public CommonResult<List<SearchCommonFieldListItemResp>> getCommonFieldList(SearchCommonFieldListReq req) {
        List<SearchCommonFieldListItemResp> data = commonFieldMapper.getCommonFieldList(req);
        return CommonResult.success(data);
    }

    private ErrorCode checkDelete(DeleteCommonFieldReq req) {
        if (req == null) {
            return ErrorCode.VALIDATE_FAILED;
        }

        if (req.getId() == null || req.getId().isEmpty()) {
            return ErrorCode.VALIDATE_FAILED;
        }

        return ErrorCode.SUCCESS;
    }

    private ErrorCode checkUpdate(UpdateCommonFieldReq req) {
        if (req == null) {
            return ErrorCode.VALIDATE_FAILED;
        }

        if (req.getId() == null || req.getId().isEmpty()) {
            return ErrorCode.VALIDATE_FAILED;
        }

        if (req.getCode() != null && !req.getCode().isEmpty() && req.getTableField() != null && !req.getTableField().isEmpty()) {
            CommonField one = getOneByCodeAndField(req.getCode(), req.getTableField());
            if (one != null && !one.getId().equals(req.getId())) {
                log.error("CommonFieldService.checkUpdate(req = {}) getOneByCodeAndField = {}, 要修改的code和field已经有值，不能重复修改", req, one);
                return ErrorCode.UNIQUE_VALID_ERROR;
            }
        }

        return ErrorCode.SUCCESS;
    }

    private ErrorCode checkAdd(AddCommonFieldReq req) {
        if (req == null) {
            return ErrorCode.VALIDATE_FAILED;
        }

        if (req.getCode() == null) {
            return ErrorCode.VALIDATE_FAILED;
        }

        if (req.getTableField() == null || req.getTableField().isEmpty()) {
            return ErrorCode.VALIDATE_FAILED;
        }

        CommonField one = getOneByCodeAndField(req.getCode(), req.getTableField());
        if (one != null) {
            log.error("CommonFieldService.checkAdd(req = {}) getOneByCodeAndField = {}", req, one);
            return ErrorCode.DATA_HAS_EXIST;
        }

        return ErrorCode.SUCCESS;
    }

    private CommonField getOneByCodeAndField(String code, String field) {
        QueryWrapper<CommonField> q = new QueryWrapper<>();
        q.eq("`code`", code);
        q.eq("`table_field`", field);
        q.last("limit 1");
        return commonFieldMapper.selectOne(q);
    }
}
